The Cegal Tools package aims to minimize time and effort for a geoscientist wanting to work with well logs using python.
Based on open source tools such as plotly, pandas and lasio, Cegal Tools allow for simple loading, manipulation and visualising of well logs from las files.
Several built in plotting methods provides an easy to use, out of the box well log tool for geoscientists using or wanting to learn python.
Cegal well tool package written by Hilde Tveit Håland & Thomas Bartholomew Grant, Cegal ASA, May 2020.
License: BSD-3-Clause
Adding logs and writing Well object as las file
Installing cegal tools package:
The purpose of Cegal Tools Plotting is create a quick and easy way to QC well logs in a jupyter notebook. It's built using plotly, so run in a different IDEs html plots will launch in your default browser.
from cegaltools.plotting import CegalWellPlotter as cwp
We'll borrow a well log from the Force 2020 Machine Learning Hackathon to demonstrate plotting.
import pandas as pd
well = pd.read_csv('ForceHackathonWell.csv')
well.head()
The well plotter assumes the index of the dataframe to be the depth curve, so we will set it to index for our well dataframe:
well.set_index('DEPTH_MD', inplace=True)
We'll print the dataframe columns to get an overview of the logs:
well.columns
help(cwp.plot_logs)
cwp.plot_logs(df=well,
logs=['GROUP','FORMATION', 'RHOB', 'GR', 'NPHI', 'DTC', 'DTS'],
log_scale_logs=['RMED', 'RDEP'],
lithology_logs='FORCE_2020_LITHOFACIES_LITHOLOGY',
lithology_proba_logs='FORCE_2020_LITHOFACIES_CONFIDENCE')
You can zoom and pan in the plot by suign the toolbar in the top left corner. Zooming along the y-axis zooms is linked for all log tracks. Hit the house symbol in the toolbar to reset the view.
The output plot is a plotly figure, if the show_fig parameter is set to false the function will return the plotly figure instead of yielding a plot.
Passing no values for the four log types will simply plot all logs as normal scale line plots:
cwp.plot_logs(df=well)
We can use the plot_correlation function to get a simple correlation plot of all input logs:
help(cwp.plot_correlation)
cwp.plot_correlation(df=well)
The coverage plot returns a bar chart with the inverse of missing values as a fraction, ie giving an overview of data coverage for the log set:
help(cwp.plot_coverage)
cwp.plot_coverage(df=well)
❤️ Data Science
You can create a well object either by reading a las file (using lasio to do the heavy lifting), or inputing a dataframe containing well log data.
Beware that creating a Well object from a dataframe requires that you set the desired depth column as index, if not the well object will not behave as expected.
from cegaltools.wells import Well
Let's make a well object from a Volve well las file. Volve data has been released as an open dataset by Equinor.
A Well object needs at minimum a filename, and if not located in the current directoy, a path to the file:
force_well = Well(filename='ForceHackathonWell.las', path=None)
There are four attributes on the well objects:
force_well.__dict__
Lasio is used to read the las file, by accessing the well_object attribute you can work with and edit the well log file as per the excellent lasio project and documentation.
If you have well log data as a dataframe you can create a Well object by passing the dataframe instead of a filename and setting there parameter from_dataframe to True.
You also have the option of passing a well name, this will be added to the las file header values if you save the Well object to a las file:
dataframe = pd.read_csv('ForceHackathonWell.csv')
dataframe.set_index('DEPTH_MD', inplace=True)
force_well_from_dataframe = Well(filename=dataframe, from_dataframe=True, dataframe_name='my_well')
force_well_from_dataframe.__dict__
You can return a pandas dataframe of the well object using the built in .df() method:
force_well.df()
The dataframe can be edited and manipulated as per the pandas documentation.
Note that if you want to write edited columns back to las format you well need to add it with the add_to_well() method.
The Cegal Well Plotter plots are also available as methods for the Well object:
force_well.plot_logs(logs=['RHOB', 'GR', 'NPHI', 'DTC', 'DTS'],
log_scale_logs=['RMED', 'RDEP'],
lithology_logs='FORCE_2020_LITHOFACIES_LITHOLOGY',
lithology_proba_logs='FORCE_2020_LITHOFACIES_CONFIDENCE')
The Well object also has the option to print a summary report for the well data:
force_well.report()
Adding logs to a Well object is done indirectly via lasios insert curve function, however the Well object requires the Well object id (sha244 hash generated for the Well object) to be passed together with new curve. The purpose for this is to assure that logs are written to the correct Well object if called from functions or in loops etc.
The new curve should be passed as a tuple with the Well object id:
(Well_object.id, new_curve)
The well id for our test well is printed below:
force_well.id
We'll write a quick function that let's us estimate the Steiber estimation for VShale.
Notice that we pass the well object and not the well dataframe to the function, that allows us to return the well id for the well the VSH estimation is created from together with the calculated values:
def create_Steiber_VSH_estimation(well_object):
linear_values = ((well_object.df()['GR'] - well_object.df()['GR'].min()) /
(well_object.df()['GR'].max() - well_object.df()['GR'].min()))
return (well_object.id, linear_values / (3 - (2*linear_values)))
create_Steiber_VSH_estimation(force_well)
We can add the output to the well object, and at the same time specify a name for the new log:
force_well.add_to_well(create_Steiber_VSH_estimation(force_well), log_name='Steiber_VSH')
force_well.plot_logs(logs=['GR','Steiber_VSH'])
To save the Well object with the added curve back to a las file we can simply call write_las on the object, while providing a name for the file to be written. The file will be saved in the current directory:
force_well.write_las(filename='our_edited_force_well')
Easy as 🥧
❤️ Data Science